package 多线程.虚假唤醒;

import lombok.SneakyThrows;

public class MyService {
    private int num = 1;
 
    /**
     * 模拟上架货物 , 始终保证有货
     */
    @SneakyThrows
    public synchronized void plus() {
        // 当货物数量大于0 , 不缺货 , 不用补 , 使当前线程休眠
        //if就会不正常
        while (num > 0) {
            System.out.println("准备补货，发现num = " + num + " plus线程" + Thread.currentThread().getName() + "休眠");
            // wait() 使当线程停在此处,  直到notify() 或者 notifyAll()被唤醒后 , 接着向下执行
            this.wait();
            System.out.println("可以补货了：num = " + num + " plus线程" + Thread.currentThread().getName() + "被唤醒");
        }
        // num 自加(补货
        num++;
        // 补货完毕 , 唤醒等待当前对象的其他线程前来竞争锁
        this.notify();
        System.out.println("补货完毕，当前num == " + num);
    }
 
    /**
     * 模拟消费货物
     */
    @SneakyThrows
    public synchronized void sub() {
        // 当货物数量num <= 0 时说明没货了 , 线程休眠
        //if就会不正常
        while (num <= 0) {
            System.out.println("准备消费，发现num = " + num + " sub线程" + Thread.currentThread().getName() + "休眠");
            this.wait();//会释放锁，所以此时其他的线程可以进来这个sub
            System.out.println("可以消费了：num = " + num + " sub线程" + Thread.currentThread().getName() + "被唤醒");
        }
        // num 自减
        num--;
        // 唤醒等待当前对象的其他线程来竞争锁
        this.notify();
        System.out.println("消费完毕，当前num == " + num);
    }
}